#ifdef RTE_APP
#ifdef LFS
#include "hwboard.h"
#include "hardware.h"
#include "config.h"
#include <string.h>
#include <plc_app.h>
extern FlashFs flash_fs;
#ifdef STM32F407xx
#define BLOCK_SIZE 16384
#else
#define BLOCK_SIZE 2048
#endif
__attribute__((section(".ccmram"))) uint8_t buf[BLOCK_SIZE];

void loader()
{
    uint8_t filename[32];
    FlashFile *fd = new FlashFile();
    fd->open_rdonly("prog.flag");
    if (fd->size() > 0)
    {
        // ch.setChar('P', 3);
        memset(filename, 0, 32);
        int len = fd->read((char *)filename, 32);
        // strcpy((char *)filename, (char *)"main.bin");
        core_debug((char *)filename);
        // fd->close();
        if (len > 5)
        {
            FlashFile *bin = new FlashFile();
            bin->open_rdonly((const char *)filename);
            if (bin->size() > 0)
            {
                int l = bin->size();
                if ((l > 0) && (l < (FLASHEND - USER_CODE_FLASH)))
                {
                    int i = 0;
                    plc_set_state(APP_FLASH_BEGIN);
                    delayMicroseconds(400);
                    for (;;)
                    {
                        // ch.setChar('W', 3);
                        plc_set_state(APP_FLASHING);
                        int rl = bin->read((char *)buf, BLOCK_SIZE);
                        if (rl > 0)
                        {

                            for (int j = 0; j < BLOCK_SIZE; j += 4)
                            {
#ifdef STM32F407xx
                                __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);
#endif
                                uint32_t ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, USER_CODE_FLASH + BLOCK_SIZE * i + j, *(uint32_t *)(buf + j));
                                switch (ret)
                                {
                                case HAL_OK:
                                    break;
                                case HAL_TIMEOUT:
                                    core_debug("HAL_FLASH_Program() timeout!\n");
                                    break;
                                case HAL_ERROR:
                                    core_debug("HAL_FLASH_Program() error 0x%08x, see *hal_flash.h for bit definitions\n", HAL_FLASH_GetError());
                                    break;
                                default:
                                    core_debug("HAL_FLASH_Program() returned unknown status %lu\n", ret);
                                }
                            }
                            core_debug("i=%d  ,remain=%d\n", i, l);
                            l -= rl;
                            i += 1;
                            delayMicroseconds(10);
                            if (l <= 0)
                                break;
                        }
                        else
                        {
                            // ch.setChar('E', 2);
                            plc_set_state(APP_FLASH_END);
                            break;
                        }
                    }
                }
            }
            // bin->close();
            flash_fs.unlink("prog.flag");
        }
    }
    else
    {
        core_debug("no flag");
    }
}
#endif
#endif